<?php

namespace slinks\core\dependencyInjectionExt\annotation;

use slinks\core\Config\Resource\FileResource;
use slinks\common\addendum\Addendum;
use slinks\common\addendum\ReflectionAnnotatedClass;
use slinks\core\DependencyInjection\Reference;
use slinks\core\DependencyInjection\Definition;
use slinks\core\DependencyInjection\ContainerBuilder;

/**
 * Annotation visitor responsible for producing sfServiceDefinition based upon annotations visited.
 * @author navid
 *
 */
class ServiceDefiningAnnotationVisitor implements \slinks\common\io\IAnnotationVisitor {

    private $container;

    public function __construct(ContainerBuilder $container) {
        $this->container = $container;

        // these are included here so adendum will pick them up with thier short name when used as doc_block annotations.
        include_once 'Service.php';

        // register the shortcut Annotation names with the Addendum
        Addendum::registerClass('Service', '\\slinks\\core\\dependencyInjectionExt\\annotation\\Service');
    }

    /**
     * This is called by the AnnotationReader when it reaches a new Class containing annotations in the filesytem.
     * @param string $classAnnotationInfo the ReflectionAnnotatedClass for the class containing the Annotations.
     * 		  This is part of the Addendum project http://code.google.com/p/addendum/
     */
    public function visit(ReflectionAnnotatedClass $classAnnotationInfo) {
        // make sure class is a valid service class.
        if ($classAnnotationInfo->hasAnnotation('Service')) {

            $serviceDefinition = ServiceDefiningAnnotationUtil::createDefinition($classAnnotationInfo);

            /* @var $serviceAnnotation Service */
            $serviceAnnotation = $classAnnotationInfo->getAnnotation('Service');

            // get service id;
            $id = ServiceDefiningAnnotationUtil::getServiceId($serviceAnnotation);
            if (!isset($id)) {
                // class name becomes service identifier.
                // TODO: how should we use the namespace to avoid name colision.
                $id = preg_replace('/\\\\/', '.', $classAnnotationInfo->getName());
            }

            $this->container->addResource(new FileResource($classAnnotationInfo->getFileName()));

            // now add the service to the container
            $this->container->setDefinition($id, $serviceDefinition);
        }
    }

}

